/*
 * @Description: vue_shop 项目服务端部署
 * @Author: pinus
 * @Email: pinus0716@163.com
 * @Git: https://gitee.com/xyf97
 * @Date: 2021-10-03 16:55:14
 * @LastEditTime: 2021-10-09 20:15:09
 */
const express = require('express')
const path = require('path')
const mount = require('mount-routes') // 根据指定的路径自动挂载路由
const compression = require('compression')
// 获取管理员逻辑模块
const managerService = require(path.join(process.cwd(), '/services/ManagerService'))
// 获取角色服务模块
const roleService = require(path.join(process.cwd(), '/services/RoleService'))

const app = express()
/*
 * 公共系统初始化
 */
app.use(express.json()) // 解析带有json的负载
app.use(express.urlencoded({ extended: false })) // 解析传递的参数放在req.body中

// 初始化数据库模块
const database = require('./modules/database.js')
database.initialize(app, err => {
  if (err) {
    console.error('>> %s', err)
  }
})

/*
 * 后台管理系统初始化
 */
// 设置跨域和相应数据格式
app.all('/api/*', (req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*') // 设置跨域
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, mytoken')
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, Authorization')
  res.setHeader('Content-Type', 'application/json;charset=utf-8')
  res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With')
  res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
  res.header('X-Powered-By', ' 3.2.1')
  if (req.method == 'OPTIONS') res.send(200)
  /*让options请求快速返回*/ else next()
})

// 初始化统一响应机制 (规范响应数据的格式)
const resextra = require('./modules/resextra')
app.use(resextra)

// 初始化 后台登录 passport 策略
const admin_passport = require(path.join(process.cwd(), '/modules/passport'))
// 设置登录模块的登录函数衔接 passport 策略
admin_passport.setup(app, managerService.login, err => {
  if (err) console.error(err)
})
// 设置 passport 登录入口点
app.use('/api/private/v1/login', admin_passport.login)
// 设置 passport 验证路径
app.use('/api/private/v1/*', admin_passport.tokenAuth)

// 获取验证模块
const authorization = require(path.join(process.cwd(), '/modules/authorization'))
// 设置全局权限
authorization.setAuthFn(function (req, res, next, serviceName, actionName, passFn) {
  if (!req.userInfo || isNaN(parseInt(req.userInfo.rid))) return res.sendResult('无角色ID分配')
  // 验证权限
  roleService.authRight(req.userInfo.rid, serviceName, actionName, function (err, pass) {
    if (err) console.error(err)
    passFn(pass)
  })
})

/*
 * 初始化路由
 */
// 带路径的用法并且可以打印出路有表
mount(app, path.join(process.cwd(), '/routes'), true)

/*
 * 挂载静态文件
 */
// 压缩传输
// app.use(compression())

app.use(express.static(path.join(process.cwd(), 'public')))

/*
 * 统一处理无响应
 */
app.use(function (req, res, next) {
  res.sendResult(null, 404, 'Not Found')
})

app.listen(8888, () => {
  console.log('server running http://localhost:8888')
})
